home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Source Code / Visual Basic Source Code.iso / vbsource / powervww / pvcalc.cpp < prev    next >
C/C++ Source or Header  |  1998-01-05  |  11KB  |  472 lines

  1. //  ____________________________________________________
  2. // |                                                    |
  3. // |  Project:     POWER VIEW INTERFACE                 |
  4. // |  File:        PVCALC.CPP                           |
  5. // |  Compiler:    WPP386 (10.6)                        |
  6. // |                                                    |
  7. // |  Subject:     Power View Calculator                |
  8. // |                                                    |
  9. // |  Author:      Emil Dotchevski                      |
  10. // |____________________________________________________|
  11. //
  12. // E-mail: zajo@geocities.com
  13. // URL:    http://www.geocities.com/SiliconValley/Bay/3577
  14.  
  15. #define uses_math
  16. #define uses_stdio
  17. #define uses_string
  18. #define uses_calc
  19. #define uses_dc
  20. #define uses_desk
  21. #define uses_dialog
  22. #define uses_editor
  23. #define uses_icons
  24. #define uses_lines
  25. #define uses_system
  26.  
  27. #include "PVuses.h"
  28.  
  29. #define cm0         cmUSER00
  30. #define cm1         cmUSER01
  31. #define cm2         cmUSER02
  32. #define cm3         cmUSER03
  33. #define cm4         cmUSER04
  34. #define cm5         cmUSER05
  35. #define cm6         cmUSER06
  36. #define cm7         cmUSER07
  37. #define cm8         cmUSER08
  38. #define cm9         cmUSER09
  39. #define cmCLR       cmUSER10
  40. #define cmBACK      cmUSER11
  41. #define cmFLIP_SIGN cmUSER12
  42. #define cmPOINT     cmUSER13
  43. #define cmPERCENT   cmUSER14
  44. #define cmMUL       cmUSER15
  45. #define cmDIV       cmUSER16
  46. #define cmADD       cmUSER17
  47. #define cmSUB       cmUSER18
  48. #define cmEVAL      cmUSER19
  49.  
  50. #define csFIRST 0
  51. #define csVALID 1
  52. #define csERROR 2
  53.  
  54. class Tcalc_display: public Titem
  55. {
  56.   public:
  57.     char status;
  58.     char number[16];
  59.     char sign;
  60.     uint op;
  61.     double operand;
  62.     Tcalc_display( void );
  63.     virtual void initialize( void );
  64. #ifndef HGR
  65.     virtual void set_palette( void );
  66. #endif
  67.     virtual void draw( void );
  68.     void clear( void );
  69.     void calc_command( uint command );
  70.     boolean clip_cut( void );
  71.     boolean clip_copy( void );
  72.     boolean clip_paste( void );
  73.  
  74.   protected:
  75.     virtual void get_focused( void );
  76.     virtual void event_handler( Tevent &ev );
  77.  
  78.   private:
  79.     void update_commands( void );
  80.     void error( void );
  81.     void set_display( double r );
  82.     void get_display( double &r );
  83.     void check_first( void );
  84. };
  85.  
  86. class Tcalculator: public Tdialog
  87. {
  88.   public:
  89.     Tcalculator( void );
  90.     virtual ~Tcalculator( void );
  91.     virtual boolean valid( uint command );
  92.  
  93.   protected:
  94.     virtual void set_palette( void );
  95.  
  96.   private:
  97.     Tcalc_display *display;
  98. };
  99.  
  100. static Tcalculator *calc_window = NULL;
  101.  
  102. //Tcalculator publics:
  103.  
  104. static Tbutton *btn( char *t, uint c )
  105. {
  106.   Tbutton *b;
  107.  
  108.   b = button( t, c );
  109.   b->shortcut = t[1];
  110.   b->set_flags( ifSELECTABLE, 0 );
  111.   return b;
  112. }
  113.  
  114. Tcalculator::Tcalculator( void ):
  115. #ifdef CYR
  116.   Tdialog( "èὬ│½á▓«░", 5, 3 )
  117. #else
  118.   Tdialog( "Calculator", 5, 3 )
  119. #endif
  120. {
  121.   set_flags( ifICONIZEABLE+ifSELECTABLE, 1 );
  122.   set_state( isON_TOP, 1 );
  123.   palette = wpTOOL;
  124.   extern_dialog( this );
  125.   vspacing( 1 ); hspace();
  126.   display = NEW( Tcalc_display );
  127.   put_item( display, display->xl, display->yl );
  128.   hor();
  129.   nl();
  130.     btn( " |~C ", cmCLR )->shortcut = kDEL;
  131.     btn( "  ", cmBACK )->shortcut = kBS;
  132.     btn( " % ", cmPERCENT );
  133.     btn( " ± ", cmFLIP_SIGN )->shortcut = '_';
  134.   nl();
  135.     btn( " 7 ", cm7 );
  136.     btn( " 8 ", cm8 );
  137.     btn( " 9 ", cm9 );
  138.     btn( " / ", cmDIV );
  139.   nl();
  140.     btn( " 4 ", cm4 );
  141.     btn( " 5 ", cm5 );
  142.     btn( " 6 ", cm6 );
  143.     btn( " * ", cmMUL );
  144.   nl();
  145.     btn( " 1 ", cm1 );
  146.     btn( " 2 ", cm2 );
  147.     btn( " 3 ", cm3 );
  148.     btn( " - ", cmSUB );
  149.   nl();
  150.     btn( " 0 ", cm0 );
  151.     btn( " . ", cmPOINT );
  152.     btn( " = ", cmEVAL )->shortcut = kENTER;
  153.     btn( " + ", cmADD );
  154.   display->set_state( isSELECTED, 1 );
  155.   focus();
  156.   xl_min = 0;
  157.   resize( xl + 1, yl + 1 );
  158.   grow_mode = gmDONT_GROW;
  159.   ~commands;
  160.   commands<<cmWIN_MOVE<<cmWIN_MINIMIZE<<cmWIN_CLOSE
  161.           <<cmWIN_RESTORE<<cmWIN_ON_TOP;
  162.   for( uint i = cmUSER00; i <= cmUSER99; i++ )
  163.     commands<<i;
  164. }
  165.  
  166. Tcalculator::~Tcalculator( void )
  167. {
  168.   calc_window = NULL;
  169. }
  170.  
  171. boolean Tcalculator::valid( uint command )
  172. {
  173.   if( ( command < cm0 ) || ( command > cmEVAL ) )
  174.     return Tdialog::valid( command );
  175.   display->calc_command( command );
  176.   return 0;
  177. }
  178.  
  179. //Tcalculator protected:
  180.  
  181. void Tcalculator::set_palette( void )
  182. {
  183.   Tdialog::set_palette();
  184.   shortcut_attr = (char) ( text_attr & 0x0F );
  185. }
  186.  
  187. //Tcalc_display publics:
  188.  
  189. Tcalc_display::Tcalc_display( void ):
  190.   Titem( 18, 1 )
  191. {
  192.   clear();
  193. }
  194.  
  195. void Tcalc_display::initialize( void )
  196. {
  197.   Titem::initialize();
  198.   owner->put_in( NEW( Tline0( xl ) ), x, y + 1 );
  199.   owner->put_in( NEW( Tline1( xl ) ), x, y - 1 );
  200. }
  201.  
  202. #ifndef HGR
  203. void Tcalc_display::set_palette( void )
  204. {
  205.   Titem::set_palette();
  206.   if( !graph_flag )
  207.   {
  208.     text_attr = rolb( text_attr, 4 );
  209.     bold_attr &= 0x0F;
  210.     bold_attr |= (char) ( text_attr & 0xF0 );
  211.   }
  212. }
  213. #endif
  214.  
  215. void Tcalc_display::draw( void )
  216. {
  217.   txtf( "%s|r%c |b%c%s|t%s", i_left_line, xl - strlen( number ) - 3, sign, number, i_right_line );
  218. }
  219.  
  220. void Tcalc_display::calc_command( uint command )
  221. {
  222.   double r;
  223.   char *p;
  224.  
  225.   if( ( status == csERROR ) && ( command != cmCLR ) ) command = 0;
  226.   switch( command )
  227.   {
  228.     case cm0:
  229.     case cm1:
  230.     case cm2:
  231.     case cm3:
  232.     case cm4:
  233.     case cm5:
  234.     case cm6:
  235.     case cm7:
  236.     case cm8:
  237.     case cm9:
  238.       check_first();
  239.       if( strlen( number ) < 15 )
  240.       {
  241.         if( !strcmp( number, "0" ) ) *number = 0;
  242.         p = strchr( number, 0 );
  243.         *(p++) = (char) ( command - cm0 + '0' );
  244.         *p = 0;
  245.       }
  246.       break;
  247.     case cmPOINT:
  248.       check_first();
  249.       if( strchr( number, '.' ) == NULL ) strcat( number, "." );
  250.       break;
  251.     case cmBACK:
  252.       check_first();
  253.       if( strlen( number ) == 1 )
  254.         strcpy( number, "0" );
  255.       else
  256.         *( strchr( number, 0 ) - 1 ) = 0;
  257.       break;
  258.     case cmFLIP_SIGN:
  259.       if( sign == ' ' ) sign = '-'; else sign = ' ';
  260.       break;
  261.     case cmPERCENT:
  262.     case cmMUL:
  263.     case cmDIV:
  264.     case cmADD:
  265.     case cmSUB:
  266.     case cmEVAL:
  267.       if( status == csVALID )
  268.       {
  269.         status = csFIRST;
  270.         get_display( r );
  271.         if( command == cmPERCENT )
  272.           switch( op )
  273.           {
  274.             case cmADD:
  275.             case cmSUB:
  276.               r = operand * r / 100; break;
  277.             case cmMUL:
  278.             case cmDIV:
  279.               r = r / 100; break;
  280.           }
  281.         switch( op )
  282.         {
  283.           case cmADD:
  284.             set_display( operand + r ); break;
  285.           case cmSUB:
  286.             set_display( operand - r ); break;
  287.           case cmMUL:
  288.             set_display( operand * r ); break;
  289.           case cmDIV:
  290.             if( r == 0 )
  291.               error();
  292.             else
  293.               set_display( operand / r );
  294.         }
  295.       }
  296.       op = command;
  297.       get_display( operand );
  298.       break;
  299.     case cmCLR:
  300.       clear();
  301.   }
  302.   redraw();
  303.   update_commands();
  304. }
  305.  
  306. boolean Tcalc_display::clip_cut( void )
  307. {
  308.   if( !clip_copy() ) return 0;
  309.   clear();
  310.   redraw();
  311.   return 1;
  312. }
  313.  
  314. boolean Tcalc_display::clip_copy( void )
  315. {
  316.   char buf[ sizeof( number ) + 1 ], *s;
  317.  
  318.   if( clipboard == NULL ) return 0;
  319.   s = buf;
  320.   if( sign == '-' ) *buf = '-', s++;
  321.   strcpy( s, number );
  322.   return clipboard->insert_string( s, 1 );
  323. }
  324.  
  325. boolean Tcalc_display::clip_paste( void )
  326. {
  327.   uint sel_len;
  328.   char buf[ sizeof( number ) + 1 ], *end_ptr;
  329.   double v;
  330.  
  331.   if( ( clipboard == NULL ) || ( clipboard->lines_selected() != 1 ) ) return 0;
  332.   sel_len = clipboard->sel_end - clipboard->sel_start;
  333.   if( !sel_len || ( sel_len >= sizeof( buf ) ) ) return 0;
  334.   clipboard->get_text( buf, clipboard->sel_start, sel_len );
  335.   buf[sel_len] = 0;
  336.   v = strtod( buf, &end_ptr );
  337.   if( ( v == HUGE_VAL ) || ( v == -HUGE_VAL ) || *end_ptr ) return 0;
  338.   set_display( v );
  339.   status = csVALID;
  340.   redraw();
  341.   return 1;
  342. }
  343.  
  344. void Tcalc_display::clear( void )
  345. {
  346.   status = csFIRST;
  347.   strcpy( number, "0" );
  348.